client/verb

/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*
///    Chat Functions        ///
*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/

	// Called when a person types something in the input box.
	returnClient()
		set hidden = 1
		if(src.Status != Available)
			setStatus("Available")

	sayMessage(msg as text)
		set
			hidden = 1
			name = ">"
		if(validMessageCheck(msg))
			setStatus("Available")
			msg = linkSearch(killNewlines(msg))
			msg = killSpaces(msg)
			for(var/client/C in Everyone)
				if(!(src.key in C.Ignored) || (src.ckey in Admins))
					var/Time = C.getTime()
					if(!C.IsTelnet() && C.Colors) C << "<b>\[</b>[Time]<b>\] <font color='#[Name_Color]'>[src.name]</font></b>: <font color='#[Text_Color]'>[msg]</font>"
					else C <<"<b>\[</b>[Time]<b>\] [src.name]</b>: [msg]"

			Messages++
			spawn(1*SECOND)
				Messages--

	emoteMessage(msg as text, p as num|null)
		set
			hidden = 1
			name = "me"
		if(validMessageCheck(msg))
			setStatus("Available")
			msg = linkSearch(killNewlines(msg))
			for(var/client/C in Everyone)
				if(!(src.key in C.Ignored) || (src.ckey in Admins))
					var/Time = C.getTime()
					if(p == 1)
						if(!C.IsTelnet() && C.Colors) C << "<b>\[</b>[Time]<b>\]</b> <font color='#[Name_Color]'>*[src.name]'s [msg]</font>"
						else C <<"<b>\[</b>[Time]<b>\]</b> *[src.name]'s [msg]"
					else
						if(!C.IsTelnet() && C.Colors) C << "<b>\[</b>[Time]<b>\]</b> <font color='#[Name_Color]'>*[src.name] [msg]</font>"
						else C <<"<b>\[</b>[Time]<b>\]</b> *[src.name] [msg]"

			Messages++
			spawn(1*SECOND)
				Messages--

	emotesMessage(msg as text)
		set
			hidden = 1
			name = "mes"
		src.emoteMessage(msg, 1)

	getTime()
		set hidden = 1
		var/Time = world.timeofday
		Time+=src.HOUR_Offset*HOUR
		Time+=src.MIN_Offset*MINUTE
		Time+=src.SEC_Offset*SECOND
		return time2text(Time,"hh:mm:ss")

	setAway(var/msg as text|null)
		set
			hidden = 1
			name = "away"
		if(LengthLimit == 0) msg = null;
		msg = copytext(msg, 1, LengthLimit+1)
		setStatus("Away", msg)

	setBusy(var/msg as text|null)
		set
			hidden = 1
			name = "busy"
		msg = copytext(msg, 1, LengthLimit+1)
		setStatus("Busy", msg)

	setAFK(var/msg as text|null)
		set
			hidden = 1
			name = "afk"
		src.setAway(msg)

	getHelp()
		set hidden = 1
		set name = "help"
		src<<Welcome



client/Stat()
	if(!IsTelnet() && src.mob)
		if(src.inactivity >= IdleTime*MINUTE && src.Status == Available)
			setStatus("Idle")

		//checkTypingStatus()

		if(Typing && src.Status == Available)
			src.mob.icon_state = "Typing"
		else
			src.mob.icon_state = src.Status_Type



client/proc

	checkTypingStatus()
		while(1)
			var/text = winget(src,"Main.Input","text")
			if(text != src.Inputted && length(text) > 2)
				if(src.STATUS_CHANGED == 0 && (src.Status == Idle || src.Status == Away || src.Status == Busy))
					winset(src,null,"command=returnClient")
				src.Inputted = text
				src.Typing = 1
			else
				Typing = 0
			sleep(1)

	messageParse(msg, quicklink, address)
		var
			StartChunk; EndChunk
			Text; TextLength
		if(findtext(msg,quicklink))

			StartChunk = copytext(msg,1,findtext(msg,quicklink))
			Text = copytext(msg,findtext(msg,quicklink))
			Text = copytext(Text,1,findtext(Text," "))
			TextLength = length(Text)
			if(quicklink == "bp:")
				Text = "<a href=\"[address][copytext(Text,length(quicklink)+1)].jpg\">[Text]</a>"
			else
				Text = "<a href=\"[address][copytext(Text,length(quicklink)+1)]\">[Text]</a>"
			EndChunk = copytext(msg,length(StartChunk)+TextLength+1,length(msg)+1)
			msg = "[StartChunk][Text][EndChunk]"
		return msg

	validMessageCheck(msg, IM)
		var retval = FALSE
		if(checkMute(src.ckey) && !IM)
			System_UserMessage(src, "You are currently muted.");

		else if(length(msg) > LengthLimit && !(ckey in Admins) || Messages>=MaxInputs)
			System_UserMessage(src, "You've said too much, would you shut up?")

		else if(hasSustenance(msg))
			retval = TRUE;

		return retval

	linkSearch(msg)
		msg = html_encode(msg) // no HTML for you
		var
			google = "http://www.google.com/search?q="
			lmgtfy = "http://lmgtfy.com/?q="
			developerforum = "http://www.byond.com/forum/?post="
			wikipedia = "http://en.wikipedia.org/wiki/"
			byondhub = "http://www.byond.com/developer/"
			byondgames = "http://www.byond.com/games/"
			byondmembers = "http://www.byond.com/members/"
			byondbash = "http://gazoot.byondhome.com/bbash/?quote="
			bash = "http://www.bash.org/?"
			qdb = "http://qdb.us/"
			//byondpeople = "http://mikaukia.net/byondpeople/"
			reference = "http://www.byond.com/members/?command=reference&path="
			youtube = "http://www.youtube.com/watch?v="
			//tracker = "http://www.byond.com/members/BYONDHelp?command=view_tracker_issue&tracker_issue="
			//forum = ""  forum:mikau:43
			//http://www.byond.com/members/Mikau/forum?id=43
		msg = messageParse(msg, "google:", google)
		msg = messageParse(msg, "lmgtfy:", lmgtfy)
		msg = messageParse(msg, "id:", developerforum)
		msg = messageParse(msg, "wiki:", wikipedia)
		msg = messageParse(msg, "hub:", byondhub)
		msg = messageParse(msg, "members:", byondmembers)
		msg = messageParse(msg, "member:", byondmembers)
		msg = messageParse(msg, "people:", byondmembers)
		msg = messageParse(msg, "bb:", byondbash)
		msg = messageParse(msg, "bash:", bash)
		msg = messageParse(msg, "qdb:", qdb)
		//msg = messageParse(msg, "bp:", byondpeople)
		msg = messageParse(msg, "ref:", reference)
		msg = messageParse(msg, "youtube:", youtube)
		msg = messageParse(msg, "yt:", youtube)
		msg = messageParse(msg, "games:", byondgames)
		//msg = messageParse(msg, "tracker:", tracker)
		return msg

	setStatus(type, var/status as text|null)
		src.Status -= src
		if(!status) status = "No reason supplied."
		if(type == "Available")
			if(src.Status!=Available && !checkMute(src.ckey) && LengthLimit != 0)
				System_WorldMessage("[src.key] has returned!")
			src.Status = Available
			src.Status_Message = ""
			src.Status_Color = AV_COLOR

		if(type == "Away")
			if(src.Status == Available && !checkMute(src.ckey) && LengthLimit != 0)
				if(status && validMessageCheck(status)) System_WorldMessage("[src.key] has gone away. ([killNewlines(html_encode(status))])")
				else System_WorldMessage("[src.key] has gone away.")
			src.Status = Away
			src.Status_Message = status
			src.Status_Color = AW_COLOR

		if(type == "Busy")
			if(src.Status == Available && !checkMute(src.ckey) && LengthLimit != 0)
				if(status)System_WorldMessage("[src.key] is now busy. ([killNewlines(html_encode(status))])")
				else System_WorldMessage("[src.key] is now busy.")
			src.Status = Busy
			src.Status_Message = status
			src.Status_Color = B_COLOR

		if(type == "Idle")
			if(src.Status == Available && !checkMute(src.ckey) && LengthLimit != 0)
				System_WorldMessage("[src.key] is now idle.")
			src.Status = Idle
			src.Status_Message = ""
			src.Status_Color = I_COLOR

		src.Status_Type = type
		src.Status += src
		src.mob.icon_state = type
		STATUS_CHANGED = 1
		spawn(10) STATUS_CHANGED = 0
		updateUsers()

	browseAddress(url)
		src<<output("<script type=\"text/javascript\">window.location=\"[url]\";</script>","Main_Browser.browser")
		winset(src,"Main_Browser","is-visible=true")

	showCode(var/person as text, var/code as num, var/text as text|null)
		if(text == "false") System_WorldMessage("[src] has posted a new <a href=\"?action=showcode;text=false;person=[person];codenum=[code]\">Show Code</a>.")
		else System_WorldMessage("[src] has posted a new <a href=\"?action=showcode;person=[person];text=true;codenum=[code]\">Show Text</a>.")
		src.returnClient()

client/verb
	reshow(var/person as text, var/code as num, var/type as num|null)
		set hidden = 1
		if(type==1) showCode(person, code, "false")
		else showCode(person, code)

proc
	hasSustenance(msg)
		if(istext(msg))
			for(var/i = 1 to length(msg))
				if(text2ascii(msg, i) > 32)
					return 1

	killNewlines(msg)
		if(!istext(msg))
			return msg
		. = ""
		var/len = length(msg)
		var/ch = 0
		for(var/i = 1; i <= len; i++)
			ch = text2ascii(msg, i)
			if(ch >= 0x20)
				. += ascii2text(ch)

	killSpaces(msg)
		var/start = 1
		if(!(findtext(msg," ",start,start+1))) return msg
		while(findtext(msg," ",start))
			start++
			if(!(findtext(msg," ",start,start+1)))
				break
		return copytext(msg,start)

	stripNonHex(X)
		if(!istext(X)) return X
		var
			len = length(X)
		. = ""
		for(var/i = 1; i <= len; i++)
			var/ch = text2ascii(X, i)
			if((ch >= 0x30 && ch <= 0x39) || (ch >= 0x41 && ch <= 0x46) || (ch >= 0x61 && ch <= 0x66))
				. += ascii2text(ch)
			else
				return


client/Topic(href,href_list[])
	..()
	switch(href_list["action"])
		if("patchnotes")
			src.browseAddress("http://dl.dropbox.com/u/16250107/Saloon/patchnotes.html")
		if("readme")
			src.browseAddress("http://dl.dropbox.com/u/16250107/Saloon/readme.html")
		if("showcode")
			var/person = href_list["person"]
			var/code = href_list["codenum"]
			var/savefile/File = new("ShowCode/[person].sav")
			var/cHeader = "<div style=\"word-wrap: break-word; width: 100%\"><pre>"
			var/cFooter = "</pre></div>"
			if(href_list["text"]=="false")
				cHeader="<pre>"
				cFooter="</pre>"
			src<<output("[cHeader][html_encode(File["Code[code]"])][cFooter]","ShowCode_Output.browser")
			winset(src,"ShowCode_Output","title=\"[person]([code])\"")
			winset(src,"ShowCode_Output","is-visible=true")